<template>
  <CustomDialog
    title="地图选点"
    :visible.sync="currentVisible"
    :append-to-body="true"
    width="900px"
    @opened="handleOpened"
  >
    <div class="amap-wrapper">
      <div class="search-box">
        <a-input-search
          ref="input"
          placeholder="请输入名称"
          style="width: 200px"
          @pressEnter="handleEnter"
          @search="handleSearch"
        />

        <div class="lnglat-addres">
          <span class="lng-lat">
            <span style="margin-right: 8px">经度：{{ lng }}</span>
            <span>纬度：{{ lat }}</span>
          </span>

          <div class="poi-name">位置：{{ address }}</div>
        </div>
      </div>
      <div ref="mapContainer" class="map-container"></div>
    </div>

    <span slot="footer" class="dialog-footer">
      <el-button @click="currentVisible = false">取 消</el-button>
      <el-button type="primary" @click="handleOk">确 定</el-button>
    </span>
  </CustomDialog>
</template>

<script>
import CustomDialog from '../CustomDialog'
export default {
  components: { CustomDialog },
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    position: {
      type: String,
      default: '',
    },
    addrs: {
      type: String,
      default: '',
    },
  },
  data() {
    return {
      map: null,
      poiPicker: null,
      address: '--',
      lng: '--',
      lat: '--',
      marker: null,
      geocoder: null,
    }
  },
  computed: {
    currentVisible: {
      get() {
        return this.visible
      },
      set(val) {
        this.$emit('update:visible', val)
      },
    },
  },
  watch: {
    lng: {
      immediate: true,
      handler() {
        const { lng, lat, map } = this

        if (lng && lat && map) {
          this.map.setCenter([lng, lat])
          this.updateMarker(lng, lat)
          this.updateAddress(lng, lat)
        }
      },
    },
  },
  mounted() {},

  beforeDestroy() {
    this.map?.off('click', this.handleMapClick)
  },
  methods: {
    handleOk() {
      this.$emit('update:position', `${this.lng},${this.lat}`)
      this.$emit('update:addrs', this.address)
      this.currentVisible = false
    },
    handleOpened() {
      if (process.browser) {
        if (!this.map) {
          const that = this
          this.$AMapLoader
            .load({
              key: 'e545eca006285231e8cc0af65862861e',
              version: '2.0',
              plugins: [
                'AMap.Scale',
                'AMap.Autocomplete',
                'AMap.ToolBar',
                'AMap.Geolocation',
                'AMap.Geocoder',
              ],
              AMapUI: {
                version: '1.1',
                plugins: ['misc/PoiPicker'],
              },
            })
            .then(() => {
              that.initAMap()
            })
            .catch((e) => {
              console.log(e)
            })
        } else {
          const { lng, lat, map } = this
          if (lng && lat && map) {
            this.initLngLat()
            this.map.setCenter([lng, lat])
            this.updateMarker(lng, lat)
            this.updateAddress(lng, lat)
          }
        }
      }
    },
    handleEnter(e) {
      this.handleSearch(e.target.value)
    },
    handleSearch(val) {
      this.poiPicker.suggest(val)
    },
    initAMap() {
      const { AMap } = window
      const map = (this.map = new AMap.Map(this.$refs.mapContainer, {
        zoom: 16,
      }))

      this.geocoder = new AMap.Geocoder()

      this.marker = new AMap.Marker({
        map,
      })

      map.addControl(new AMap.Scale())
      map.addControl(new AMap.ToolBar())

      map.on('click', this.handleMapClick)

      this.initAMapUI(map)
      this.initLngLat()
    },

    initLngLat() {
      const [lng, lat] = this.position.split(',')
      this.lng = lng
      this.lat = lat
    },

    handleMapClick(e) {
      const { lng, lat } = e.lnglat
      this.lng = lng
      this.lat = lat
    },
    updateMarker(lng, lat) {
      this.marker.setPosition([lng, lat])
    },

    updateAddress(lng, lat) {
      const { geocoder } = this
      const that = this
      geocoder.getAddress([lng, lat], function (status, result) {
        if (status === 'complete' && result.regeocode) {
          const address = result.regeocode.formattedAddress
          that.address = address
          // that.$emit('update:position', `${lng},${lat}`)
          // that.$emit('change', { lng, lat })
        } else {
          console.error('根据经纬度查询地址失败')
        }
      })
    },

    initAMapUI() {
      const { AMapUI } = window

      // 搜索poi
      const poiPicker = new AMapUI.PoiPicker({
        input: this.$refs.input.$el.firstElementChild,
      })
      poiPicker.on('poiPicked', (poiResult) => {
        // console.log('poiResult', poiResult)
        const {
          location: { lng, lat },
          address,
        } = poiResult.item

        this.lng = lng
        this.lat = lat
        this.address = address
      })

      this.poiPicker = poiPicker
    },
  },
}
</script>
<style lang="scss" scoped>
.amap-wrapper {
  height: 100%;
  position: relative;

  .search-box {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    background-color: rgba(0, 0, 0, 0.3);
    z-index: 1;
    display: flex;
    align-items: center;
    padding-left: 10px;
  }

  .lnglat-addres {
    color: #fff;
    padding-left: 12px;
  }

  .map-container {
    width: 100%;
    height: 100%;
  }
}
</style>
